#ifndef __HASH_HPP__
#define __HASH_HPP__

#include <functional>
#include <map>

namespace metrics
{
    class Hash
    {
    public:
        Hash() {}
        virtual ~Hash() {}

    public:
        // //1
        // std::size_t operator()()
        // {
        //     return hash_val();
        // }

        //2
        // template <typename... Types>
        // inline std::size_t hash_val(const Types &...args)
        // {
        //     std::size_t seed = 0;
        //     hash_val(seed, args...);
        //     return seed;
        // }

        //3
        template <typename T, typename... Types>
        inline void hash_val(std::size_t &seed, const T &val, const Types &...args)
        {
            hash_combine(seed, val);
            hash_val(seed, args...);
        }

        //4
        template <typename T>
        inline void hash_combine(std::size_t &seed, const T &val)
        {
            seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        }

        //5,在szieof args... = 1时(递归结束)调用
        template <typename T>
        inline void hash_val(std::size_t &seed, const T &val)
        {
            hash_combine(seed, val);
        }
    };

    std::size_t hash_labels(const std::map<std::string, std::string> &labels);
    
} // namespace metrics

#endif // __HASH_HPP__